/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#ifndef __VSTACK_H__
#define __VSTACK_H__

#include <stack>
#include "../Exceptions/vExceptions.h"
#include "../Macros/vMemoryMacros.h"


namespace Vendetta {
	template<class T> class vStack {
	public:
		vStack() { }

		vStack(const vStack& arr) {
			mData = arr.mData;
		}

		~vStack() { }

		vStack& operator=(const vStack& arr) {
			if (this != &arr) {
				mData = arr.mData;
			}

			return *this;
		}

		vStack& operator<<(const T& val) {
			mData.push(val);

			return *this;
		}

		inline vVoid Push(const T& val) {
			mData.push(val);
		}

		inline vStack<T>& Pop() {
			if (mData.empty()) {
				throw vFatalException("No elements on the stack. In vStack::Pop.");
			}
			mData.pop();

			return *this;
		}

		inline vUInt Size() const {
			return static_cast<vUInt>(mData.size());
		}

		inline vBool IsEmpty() const {
			return mData.empty();
		}

		inline T& Top() {
			if (mData.empty()) {
				throw vFatalException("No elements on the stack. In vStack::Top.");
			}
			return mData.top();
		}

		inline const T& Top() const {
			if (mData.empty()) {
				throw vFatalException("No elements on the stack. In const vStack::Top.");
			}
			return mData.top();
		}

		inline vVoid Clear() {
			while (mData.size() > 0) {
				mData.pop();
			}
		}

	private:
		std::stack<T> mData;
	};
}

#endif //__VSTACK_H__